#include "SchmidtCAM.h"

/*
#define SPI_PS_READOUT_DRV   1
#define SPI_PS_IDELAY_CTRL   2
*/


void set_SPI_PS_A3_new( uint32_t* gpio_reg, uint32_t A2 ){
    if( A2 == 0 )
        clrbit(*gpio_reg, BIT_SPI_PS_A3_NEW);
    
    if( A2 == 1 )
        setbit(*gpio_reg, BIT_SPI_PS_A3_NEW);
}

void set_SPI_PS_A2_new( uint32_t* gpio_reg, uint32_t A2 ){
    if( A2 == 0 )
        clrbit(*gpio_reg, BIT_SPI_PS_A2_NEW);
    
    if( A2 == 1 )
        setbit(*gpio_reg, BIT_SPI_PS_A2_NEW);
}

void set_SPI_PS_A1_new( uint32_t* gpio_reg, uint32_t A1 ){
    if( A1 == 0 )
        clrbit(*gpio_reg, BIT_SPI_PS_A1_NEW);
    
    if( A1 == 1 )
        setbit(*gpio_reg, BIT_SPI_PS_A1_NEW);
}

void set_SPI_PS_A0_new( uint32_t* gpio_reg, uint32_t A0 ){
    if( A0 == 0 )
        clrbit(*gpio_reg, BIT_SPI_PS_A0_NEW);
    
    if( A0 == 1 )
        setbit(*gpio_reg, BIT_SPI_PS_A0_NEW);
}


void SPI_PS_MUX16_new( uint32_t *axi_spi_ps_ctrl_reg, uint32_t SPI_PS_OPT ){
    
    uint32_t A3 = 0;
    uint32_t A2 = 0;
    uint32_t A1 = 0;
    uint32_t A0 = 0;
    
    switch (SPI_PS_OPT) {
    
        case SPI_PS_READOUT_DRV:    // 0,0,0,1
            A3 = 0;
            A2 = 0;
            A1 = 0;
            A0 = 1;
            break;

        case SPI_PS_IDELAY_CTRL:     // 0,0,1,0
            A3 = 0;
            A2 = 0;
            A1 = 1;
            A0 = 0;
            break;
            
        default:    // 0,0,0,0
            A3 = 0;
            A2 = 0;
            A1 = 0;
            A0 = 0;
    }

    set_SPI_PS_A3_new( axi_spi_ps_ctrl_reg, A3 );
    set_SPI_PS_A2_new( axi_spi_ps_ctrl_reg, A2 );
    set_SPI_PS_A1_new( axi_spi_ps_ctrl_reg, A1 );
    set_SPI_PS_A0_new( axi_spi_ps_ctrl_reg, A0 );
}

void SPI_PS_SCLK_new( uint32_t *axi_spi_ps_ctrl_reg ){
    clrbit(*axi_spi_ps_ctrl_reg, BIT_SPI_PS_SCLK_NEW);
    // usleep(10);
    setbit(*axi_spi_ps_ctrl_reg, BIT_SPI_PS_SCLK_NEW);
    // usleep(10);
}

void SPI_PS_RST_new( uint32_t *axi_spi_ps_ctrl_reg ){
    clrbit(*axi_spi_ps_ctrl_reg, BIT_SPI_PS_RST_NEW);
    // usleep(10);
    setbit(*axi_spi_ps_ctrl_reg, BIT_SPI_PS_RST_NEW);
    // usleep(10);
    clrbit(*axi_spi_ps_ctrl_reg, BIT_SPI_PS_RST_NEW);
    // usleep(10);
}


void SPI_PS_SET_ADDR_new( uint32_t *axi_spi_ps_ctrl_reg, uint16_t addr ){
    uint32_t addr_tmp = *axi_spi_ps_ctrl_reg & 0xffff0000; // 仅使用低16位bits
    addr_tmp = addr_tmp | addr;
    *axi_spi_ps_ctrl_reg = addr_tmp;
}

void SPI_PS_SET_DATA_new( uint32_t *axi_spi_ps_data_reg, uint32_t data ){
    *axi_spi_ps_data_reg = data;
}

void SPI_PS_SEND_DATA_new(  uint32_t *axi_spi_ps_ctrl_reg,
                            uint32_t *axi_spi_ps_data_reg,
                            uint32_t *reg_val, 
                            uint32_t reg_num,
                            uint32_t SPI_PS_OPT ){
    
    // 设置片选信号
    SPI_PS_MUX16_new( axi_spi_ps_ctrl_reg, SPI_PS_OPT );

    // 复位
    SPI_PS_RST_new( axi_spi_ps_ctrl_reg );

    // 开始传输数据
    uint16_t i;
    for( i=0; i<reg_num; i++ ){
        // set address
        SPI_PS_SET_ADDR_new( axi_spi_ps_ctrl_reg, i);

        // set data
        SPI_PS_SET_DATA_new( axi_spi_ps_data_reg, reg_val[i] );

        // pulse a sclk
        SPI_PS_SCLK_new( axi_spi_ps_ctrl_reg );
    }

}
